Skip to content

读[高性能响应式Web开发实战]有感

李光毅 著 2016年7月第一版

写在最前

我很喜欢这本书的前言一文中的一段话,就是:当然终究有一天这本书的内容也会落伍和被淘汰,只是时间的问题罢了。 作者太谦虚了,给我的感觉是作者很有风度,这个谦虚的自嘲很6。确实这本书最后一章对构建工具的介绍只介绍了grunt,技术栈比较落后,但是可能是顺带提一下,性能方面的讲解还是很透彻的,作者在性能优化方面有非常深刻的见解。这本书是一本好书,值得读一读。

总的收获

这本书是我看过的关于性能方面讲解的最深刻和最细致的一本书。里面有很多非常好的观点。能给我展示一个非常完整和完善以及非常优秀的解决方案。通过对比多个方案来得出性能最优方案。比如浏览器页面放大后,为什么字体没有模糊。其实答案很简单,但是真的我从来没有想过这个问题,看到后,我眼睛一亮,作者想的好细致,答案就是字体是可伸缩适量,放大不会有损。所以我就想到了SVG,SVG的思想可能就是来源于此吧。

关于像素

PPI:每英寸有多少像素,也就是像素密度。PPI也可以称为DPI,每英寸有多少点数。在LCD显示器中,每一个dot都是由三个分别显示红绿蓝的子像素组成的。

设备像素和物理像素

像素密度中的像素是指设备像素,也是指物理像素。

CSS像素

CSS像素单位为px,它是相对像素,我们可以联想一下em、rem等,其实相对的思想是共通的。CSS像素默认是与系统分辨率下像素大小相等。正常情况下(标清设备中),一个px应该是与一个设备像素相等。但是在高清设备或者用户缩放的过程中,一个px可以大于或等于多个设备像素。比如你把浏览器放大了,其实是浏览器自己把一个CSS像素的面积放大了。

视口

视口viewport的出现是为了解决桌面端浏览器与移动端设备浏览器在渲染页面时的差异,也就是控制页面布局渲染的。

桌面端视口和移动设备端视口区别

桌面端视口的特点是:浏览器区域大小受限于显示器屏幕大小,也意味着页面的宽度不会超过浏览器屏幕宽度。举个最简单的例子:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<style>
    div{
        width:10%;
    }
</style>

<body>
    <div>这是宽度为10%的元素</div>
</body>

</html>

上面的body宽度默认是100%,比如在1920*1080的显示器上浏览器最大化的情况下,以桌面视口的定义,div的实际宽度最大只能是系统分辨率的10%,也就是最大宽度为192px,如果手机继承的任然是桌面视口的设定。那么在分辨率为375p的手机上浏览。显示的只能是一个37.5px的元素,这显然无法正常显示。所以移动设备的视口定义与桌面不同。那么桌面是怎么做的呢。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>

</body>
</html>

比如布局的默认宽度是980px,用移动设备浏览器打开后,发现页面宽度和屏幕是刚好相等。为什么会这样?浏览器做了两件事

  1. 用980px像素宽度渲染页面。
  2. 将页面缩放至宽度与系统宽度一致。

PS:本质上并没有改变页面(视口)的大小,只是改变了视口的缩放比例。

meta出现

设计人员希望以页面的宽度来渲染页面,能自然自适应到系统宽度,于是name=viewport的meta标签出现了。meta可以设置视口大小,比如下面这个 <meta name="viewport" content="width=375">表示以375 CSS像素渲染页面。initial-scale参数是用来控制渲染时缩放视口的比例。如果未加该参数,浏览器自动会将页面缩放至浏览器宽度一致。

我们希望以系统分辨率的宽度来渲染,尽可能的避免缩放,比如375的页面设计,我们希望设备能以375px宽度来渲染布局,而不是用桌面端渲染然后进行缩放。

但是如果把width设置成了375,那么有一个问题,不同设备的系统分辨率是不一致的,就算同一种设备上,横竖都会让渲染方式不同,那么怎么解决呢

我们可以不用关心具体的数值,只要告诉浏览器:无论什么设备,请按照系统分辨率宽度渲染。也就是把width设置为device-width

浏览器宽度就是浏览器可视区域宽度,浏览器可视区域大小决定了页面的布局,浏览器窗口多大,就会以多大的尺寸影响页面布局。这里的可视区域大小就是布局视口(layout viewport),简称视口(viewport)。

PS:html设置宽度为100%,就是让html宽度始终与浏览器宽度保持一致,也就是和视口宽度保持一致。

为什么移动浏览器

系统分辨率是指视口大小。

CSS

媒体查询的优先级策略

优先级策略就是查询的组织方式,分为移动优先和桌面优先。移动优先是使用指希望页面优先采用移动样式,特征是使用min-width匹配页面宽度。下面代码就是移动优先。

@media (min-width: 320px) {

}
@media (min-width: 1024px) {

}

这个是桌面优先

@media (max-width: 320px) {

}
@media (max-width: 1024px) {

}

选择:使用移动优先方案,因为做加法容易,移动优先会较好的做到代码简洁。

px => em => rem

em是相对单位,em作为字体单位时,与%单位是等价的,都是相对于最近父元素设置字体大小。

两种重置样式的本质区别

  1. reset.css是通过重置样式以消除不同浏览器下各个元素的样式差异,强制把所有元素样式都放到同一起跑线上。
  2. normalize.css是承认差异的存在,它在保留浏览器默认样式基础上,通过新增代码使元素样式在不同浏览器下的行为保持一致,并且修复了一些常见bug。

优劣:选择reset.css,就还需要额外的工作用于恢复 部分样式。选择normalize.css,会包含一些冗余的代码,还有仍然需要对一部分元素默认样式内外边距重置为0,也就是写一些重置样式。

响应式图片

响应式图片的需求

  • 图片能够随父容器宽度变化而变化。
  • 同时宽度受限于父容器,不可按照图片原始尺寸展现。

响应式的几种方案

  1. 将图片的最大宽度设置为100%,这样不会产生被拉伸现象。
  2. 基于屏幕分辨率,无法满足移动端要求。
  3. 基于视口,不关心屏幕的分辨率,只关心视口。
  4. 基于设备像素比DPR,现在主流方案。
  5. 基于美术设计,为不同场景准备的图片是由同一张大图等比缩放而来的。

PS:DPR是为了解决PPI过高导致单个像素过小而难以辨别,通常设备分辨率下每个像素会等于多个设备像素,而这个CSS像素与设备像素的比值称为设备像素比。然后根据这个比值,来确定提高高清的图片的倍数,是2倍、3倍还是4倍。

放弃图片

  1. 将图片自身转化为文本作为元素图片的URI使用,也就是通过Base64编码,这类URI成为数据URI(data URI)
  2. CSS形状
  3. 使用图标字体代替实体图片,图标是icon的中午翻译,图标字体是基于伪元素实现的。用来装饰按钮或者链接。

关于一个性能有关的问题

看下面代码

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<style>
  @media all and (max-width: 600px) {
    #test{
      display: none;
    }
  }
</style>

<body>
<div id="test">
  <img src="1.png" alt="">
</div>
</body>

</html>

假设打开页面时,页面的宽度不足600px,图片就会被隐藏不可见,但是实际上图片请求仍然被发出了。如果有很多这种图片,则会无形中影响页面的加载速度。包括隐藏的背景图片,也会被请求。

能使用CSS实现的功能请不要使用JS

脚本是性能成很高的工具,实现同一效果的前提下采用脚本实现的方式会导致帧数降低。在内容不断增加的情况下,CSS实现的性能会远高于JS脚本实现的性能。

Released under the MIT License.